﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DAL;
using System.Data;
using System.IO;
using System.Configuration;
using System.Transactions;
using System.Data.Linq;
using System.ComponentModel;
using UtilityExtensions;

namespace BOL.Ventas
{
    public class DocumentoVentaBL
    {
        public int Add(
            DateTime fecha, 
            int idDocumentoTipo,
            string numDocumento,
            int idCliente,
            string comentario,
            int idOrdenVentaitem,
            int idMoneda,
            int idProyecto,
            List<DocumentoVentaitemInfo> entitylist)
        {
             using (TransactionScope ts = new TransactionScope())
            {

                //DataSet dsDiferencias = new DataSet();
                dbGestionDataContext _db =
                    new dbGestionDataContext(Parametros.strConnString);

                int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());
                 Empleado empleado = _db.Empleados.Single(p=>p.idInternal==idEmpleadoEmisor);
                 DAL.Cliente cliente = _db.Clientes.Single(p => p.idInternal == idCliente);

                 DocumentoVenta documentoVenta = new DocumentoVenta();
                 

                 Moneda moneda = _db.Monedas.Single(p => p.idInternal == 4); //por la moneda dolares
                 decimal tipoCambioDollar = moneda.getTipoCambio(_db, fecha);

                 Folio folio = _db.Folios.Single(p => p.idProyecto == idProyecto & p.idDocumentoTipo == idDocumentoTipo & p.bitActivo==true);
                    
               
                 documentoVenta.AddSet(
                    _db,
                    idProyecto,
                    fecha,
                    cliente.idInternal,
                    cliente.idTipoDocumento,
                    cliente.numDocumento,
                    cliente.descripcion,
                    cliente.Direccion.descripcion,
                    idMoneda,
                    idDocumentoTipo,
                    folio.serie,
                    numDocumento,//folio.GetActualwithFormato(folio.actual),
                    tipoCambioDollar,
                    idOrdenVentaitem,
                    comentario,
                    idEmpleadoEmisor,
                    empleado.descripcion,
                    11 // facturado
                 );

                 //actualizamos el folio
                  //!ordenVenta.FormatoVenta.bitBono, //no afecto si esta con bono
                 

                _db.SubmitChanges();
                 

                
                    foreach (DocumentoVentaitemInfo drw in entitylist)
                    {
                        

                            DocumentoVentaItem ordenVentaItem = new DocumentoVentaItem();
                                        ordenVentaItem.AddSet(_db,
                                               drw.codigo,
                                               drw.descripcion,
                                               drw.total,
                                               drw.IGVTotal,
                                               drw.subTotal,
                                               documentoVenta.idInternal,
                                               drw.idOrdenVentaFormato);
                                        
                                        var OrdenVentaFormato = _db.OrdenVentaFormatos.Single(p => p.idInternal == drw.idOrdenVentaFormato);
                                        OrdenVentaFormato.UpdateFacturado(documentoVenta.idInternal);
                                        _db.SubmitChanges();

                    }

                    documentoVenta.updateTotal(_db);
                    _db.SubmitChanges();
               
                
                 //carga los requisitos necesarios  para la generacion de requisitos
                 // para el caso de copropietario verficamos que se de el caso de un  Natural y otro Empresa
                 //DAL.Cliente cliente =_db.Clientes.Single(p=>p.idInternal==idCliente);

                 //caso del copropietario


                ts.Complete();
                return documentoVenta.idInternal;


                
            }
        }




        public int AddNotaCredito(dbGestionDataContext _db,
           DateTime fecha,
           string numDocumento,
           int idCliente,
           string comentario,
           int idOrdenVentaitem,
           int idMoneda,
           int idProyecto,
            List<int> documentoRef,
           List<DocumentoVentaitemInfo> descripcion)
        {
            using (TransactionScope ts = new TransactionScope())
            {

                 
                int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());
                Empleado empleado = _db.Empleados.Single(p => p.idInternal == idEmpleadoEmisor);
                DAL.Cliente cliente = _db.Clientes.Single(p => p.idInternal == idCliente);

                DocumentoVenta documentoVenta = new DocumentoVenta();


                Moneda moneda = _db.Monedas.Single(p => p.idInternal == 4); //por la moneda dolares
                decimal tipoCambioDollar = moneda.getTipoCambio(_db, fecha);

                int idDocumentoTipo = 6;//nota de credito
                
                Folio folio = _db.Folios.Single(p => p.idProyecto == idProyecto & p.idDocumentoTipo == idDocumentoTipo & p.bitActivo == true);

                //la serie es por proyecto?

                documentoVenta.AddSet(
                   _db,
                   idProyecto,
                   fecha,
                   cliente.idInternal,
                   cliente.idTipoDocumento,
                   cliente.numDocumento,
                   cliente.descripcion,
                   cliente.Direccion.descripcion,
                   idMoneda,
                   idDocumentoTipo,
                   folio.serie,
                   numDocumento,//folio.GetActualwithFormato(folio.actual),
                   tipoCambioDollar,
                   idOrdenVentaitem,
                   comentario,
                   idEmpleadoEmisor,
                   empleado.descripcion,
                   11 // facturado
                );

                //actualizamos el folio
                //!ordenVenta.FormatoVenta.bitBono, //no afecto si esta con bono


                _db.SubmitChanges();



                foreach (DocumentoVentaitemInfo drw in descripcion)
                {


                    DocumentoVentaItem ordenVentaItem = new DocumentoVentaItem();
                    ordenVentaItem.AddSet(_db,
                           drw.codigo,
                           drw.descripcion,
                           drw.total,
                           drw.IGVTotal,
                           drw.subTotal,
                           documentoVenta.idInternal,
                           drw.idOrdenVentaFormato);

                    var OrdenVentaFormato = _db.OrdenVentaFormatos.Single(p => p.idInternal == drw.idOrdenVentaFormato);
                    OrdenVentaFormato.UpdateFacturado(documentoVenta.idInternal);
                    _db.SubmitChanges();

                }
                documentoVenta.updateTotal(_db);

                foreach (var item in documentoRef)
                {
                    DAL.DocumentoVentaRef referencia = new DocumentoVentaRef();

                    referencia.idDocumentoVenta = documentoVenta.idInternal;
                    referencia.idDocumentoVentaRef = item;
                    _db.DocumentoVentaRefs.InsertOnSubmit(referencia);
                }
                
                _db.SubmitChanges();
                
                //carga los requisitos necesarios  para la generacion de requisitos
                // para el caso de copropietario verficamos que se de el caso de un  Natural y otro Empresa
                //DAL.Cliente cliente =_db.Clientes.Single(p=>p.idInternal==idCliente);

                //caso del copropietario
                
                ts.Complete();
                return documentoVenta.idInternal;

            }
        }




        //public int UpdateOrdenVenta( int idOrdenVenta,
        //                        bool bitcopropietario,
        //                        int? idCoCliente,
        //                      int idFormatoVenta,
        //                      string comentario,
        //                      int? idBanco,
        //                      bool bitCuentaAhorro,
        //                      DataSet entitylist)
        //{
        //    using (TransactionScope ts = new TransactionScope())
        //    {

        //        //DataSet dsDiferencias = new DataSet();
        //        dbGestionDataContext _db =
        //            new dbGestionDataContext(Parametros.strConnString);

        //        int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());
        //        Empleado empleado = _db.Empleados.Single(p => p.idInternal == idEmpleadoEmisor);

        //        OrdenVenta ordenVenta = _db.OrdenVentas.Single(p=>p.idInternal==idOrdenVenta);
        //        ordenVenta.UpdateSet(
        //            bitcopropietario?idCoCliente:null,
        //            bitcopropietario,
        //            idFormatoVenta,
        //            idEmpleadoEmisor,                    
        //            empleado.usuario,
        //            comentario,
        //             bitCuentaAhorro==true?1:2,
        //            idBanco);

        //        _db.SubmitChanges();
        //        DataSet dsDiferencias = new DataSet();

        //        if (entitylist.HasChanges())
        //        {
        //            dsDiferencias.Merge(entitylist.GetChanges());

        //            foreach (DataRow drw in dsDiferencias.Tables["OrdenVentaItemInfo"].Rows)
        //            {
        //                if (drw.RowState == DataRowState.Modified)
        //                {
        //                    OrdenVentaItem ordenVentaitem = _db.OrdenVentaItems.Single(p => p.idInternal == drw.Field<int>("idInternal"));
        //                    ordenVentaitem.UpdateSet(drw.Field<bool>("bitFinanciado"));
        //                    _db.SubmitChanges();

        //                }
        //                if (drw.RowState == DataRowState.Deleted)
        //                {
        //                    drw.RejectChanges();
        //                    OrdenVentaItem ordenVentaitem = _db.OrdenVentaItems.Single(p => p.idInternal == drw.Field<int>("idInternal"));

        //                    _db.OrdenVentaItems.DeleteOnSubmit(ordenVentaitem);
        //                    _db.SubmitChanges();
        //                }


        //                if (drw.RowState == DataRowState.Added)
        //                {
        //                    var UI = _db.UIs.Single(p => p.idInternal == drw.Field<int>("idUI"));

        //                    OrdenVentaItem ordenVentaItem = new OrdenVentaItem();
        //                    ordenVentaItem.AddSet(_db,
        //                           ordenVenta.idInternal,
        //                           drw.Field<int>("idUI"),
        //                           UI.idMoneda,
        //                           drw.Field<decimal>("total"),
        //                           drw.Field<bool>("bitFinanciado"));

        //                }

        //            }
        //        }
        //        _db.SubmitChanges();

        //        // para los requisitos
        //        //agregamos los valores que falten  si fueron cambiados

        //        //var requisitosList = from a in _db.UIRequisitoItems
        //        //                     where a.bitCopropietario == ordenVenta.bitCopropietario
        //        //                             & (a.bitPersona != ordenVenta.Cliente.bitEsJuridica
        //        //                             | a.bitEmpresa == ordenVenta.Cliente.bitEsJuridica)
        //        //                     select a;

        //        //foreach (var item in requisitosList)
        //        //{
        //        //    OrdenVentaRequisito ovRequisito = new OrdenVentaRequisito();
        //        //    ovRequisito.AddSet(_db, item.idInternal, false, ordenVenta.idInternal, null);

        //        //    _db.SubmitChanges();
        //        //}
                
        //        ts.Complete();
        //        return ordenVenta.idInternal;



        //    }
        //}


        public void  Delete(dbGestionDataContext _db,int idDocumentoVenta)

        {
            using (TransactionScope ts = new TransactionScope())
            {

                //DataSet dsDiferencias = new DataSet();
              

                int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());

                DocumentoVenta documentoVenta = _db.DocumentoVentas.Single(p => p.idInternal == idDocumentoVenta);

                foreach (var item in documentoVenta.OrdenVentaFormatos)
                {
                    item.DeleteFacturado();
                }

                _db.DocumentoVentaItems.DeleteAllOnSubmit(documentoVenta.DocumentoVentaItems);
                _db.DocumentoVentas.DeleteOnSubmit(documentoVenta);
               
                _db.SubmitChanges();
                ts.Complete();
         }

        }

        public void Anular(int idDocumentoVenta)
        {
            using (TransactionScope ts = new TransactionScope())
            {

                //DataSet dsDiferencias = new DataSet();
                dbGestionDataContext _db =
                    new dbGestionDataContext(Parametros.strConnString);

                int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());
                Empleado empleado = _db.Empleados.Single(p => p.idInternal == idEmpleadoEmisor);

                DocumentoVenta documentoVenta = _db.DocumentoVentas.Single(p => p.idInternal == idDocumentoVenta);
                documentoVenta.AnularSet(1, idEmpleadoEmisor, empleado.descripcion);
                // anulamos el ordenventaid

                foreach (var item in documentoVenta.OrdenVentaFormatos)
	            {
                    item.DeleteFacturado();
	            }

                _db.SubmitChanges();
                ts.Complete();
            }

        }

        public List<DocumentoVentaitemInfo> GetDocumentoVentaItem(int idDocumentoVenta)
        {
            var q = from a in DbUtil.Db.DocumentoVentaItems
                    where a.idDocumentoVenta == idDocumentoVenta
                    select new DocumentoVentaitemInfo
                    {
                        codigo=a.codigo,
                        descripcion=a.descripcion,
                        idDocumentoVenta=a.idDocumentoVenta,
                        idInternal=a.idInternal,
                        idOrdenVentaFormato = a.idOrdenVentaFormato,
                        IGVTotal=a.IGVTotal,
                        IGVTotalStr=a.IGVTotal.ToString(),
                        subTotal=a.subTotal,
                        subTotalStr=a.subTotal.ToString(),
                        total=a.total,
                        totalStr=string.Format("{0}{1:N}",a.DocumentoVenta.Moneda.simbol,a.total),
                        
                    };

                   return q.ToList();
        }

        public List<DocumentoVentaRefInfo> GetDocumentoVentaRef(int idDocumentoVenta)
        {
            var q = from a in DbUtil.Db.DocumentoVentaRefs
                    where a.idDocumentoVenta == idDocumentoVenta
                    select new DocumentoVentaRefInfo
                    {
                        documentoVentaRefStr = string.Format("{0}/{1}-{2}", a.DocumentoVenta1.DocumentoTipo.abreviacion, a.DocumentoVenta1.serie, a.DocumentoVenta1.numeroDoc),
                        idDocumentoVenta=a.idDocumentoVenta,
                        idDocumentoVentaRef=a.idDocumentoVentaRef
                    };

            return q.ToList();
        }

        public List<DocumentoVentaPrint> LoadBoletaPrint(int idDocumentoVenta)
        {
            var q = from a in DbUtil.Db.DocumentoVentaItems
                    where a.idInternal == idDocumentoVenta
                    select new DocumentoVentaPrint
                    {
                        cliente = a.DocumentoVenta.nombreCliente,
                        descripcion = a.descripcion,
                        direccion = a.DocumentoVenta.direccion,
                        docCliente = a.DocumentoVenta.documentoCliente,
                        fecha = a.DocumentoVenta.fecha.ToShortDateString(),
                        total = String.Format("{0:N}", a.DocumentoVenta.total),
                        totalItem = String.Format("{0:N}", a.total),
                         moneda=a.DocumentoVenta.Moneda,
                          
                    };


            return q.ToList();

        }

        public List<DocumentoVentaPrint> LoadFacturaPrint(int idDocumentoVenta)
        {
            var q = from a in DbUtil.Db.DocumentoVentaItems
                    where a.idDocumentoVenta == idDocumentoVenta
                    select new DocumentoVentaPrint
                    {
                        cliente = a.DocumentoVenta.nombreCliente,
                        descripcion = a.descripcion,
                        direccion = a.DocumentoVenta.direccion,
                        docCliente = a.DocumentoVenta.documentoCliente,
                        fecha = a.DocumentoVenta.fecha.ToShortDateString(),
                        total = String.Format("{0:N}", a.DocumentoVenta.total),
                        totalLET=a.DocumentoVenta.total,
                        moneda=a.DocumentoVenta.Moneda,
                        totalItem = String.Format("{0:N}", a.total)
                    };


            return q.ToList();

        }


        public IQueryable<OrdenVentaFormato> GetConceptosPendientesFacturacion(int idordenVentaItem)
        {
            //no utilizar los anulados
            //

            var o = from a in DbUtil.Db.DocumentoVentaItems
                    where
                    a.OrdenVentaFormato.idOrdenVentaItem == idordenVentaItem
                    & a.DocumentoVenta.bitAnulado == false
                    select a.idOrdenVentaFormato;

            var q = from a in DbUtil.Db.OrdenVentaFormatos
                    where !o.Contains(a.idInternal)
                    & a.total>0
                    & a.total-a.totalFin> 0
                    & a.idOrdenVentaItem == idordenVentaItem
                    select a;

            return q;
        }
    }
}
